package com.lmt.controller;

import com.google.common.collect.Maps;
import com.lmt.entity.User;
import com.lmt.service.AggregationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import rx.Observable;
import rx.Observer;

import java.util.HashMap;

/**
 * RxJava
 * Date 2018/07/01
 *
 * @author MT-Lin
 */
@RestController
public class AggregationController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private final AggregationService aggregationService;

    @Autowired
    public AggregationController(AggregationService aggregationService) {
        this.aggregationService = aggregationService;
    }

    @GetMapping("/findUsersById")
    public DeferredResult<HashMap<String, User>> aggregate(@RequestParam(value = "id") String id){
        return this.toDefferedResult(this.aggregateObservable(id));
    }

    /**
     * 合并两个或多个Observables发射出的数据项，根据指定的函数变换他们
     * @param id id
     * @return 合并结果
     */
    private Observable<HashMap<String, User>> aggregateObservable(String id) {
        return Observable.zip(
                this.aggregationService.findUserByIdFromProvider(id),
                this.aggregationService.findUserByIdFromConsumer(id),
                (userFromProvider, userFromConsumer) -> {
                    HashMap<String, User> map = Maps.newHashMap();
                    map.put("userFromProvider", userFromProvider);
                    map.put("userFromConsumer", userFromConsumer);
                    return map;
                }
        );
    }

    private DeferredResult<HashMap<String, User>> toDefferedResult(Observable<HashMap<String, User>> details) {
        DeferredResult<HashMap<String, User>> result = new DeferredResult<>();
        // 订阅
        details.subscribe(new Observer<HashMap<String, User>>() {
            @Override
            public void onCompleted() {
                logger.warn("完成。。。");
            }

            @Override
            public void onError(Throwable e) {
                logger.error("发生错误。。。", e);
            }

            @Override
            public void onNext(HashMap<String, User> userDetails) {
                result.setResult(userDetails);
            }
        });
        return result;
    }
}
